#include "box_server.h"
using namespace std;

#define DEFAULT_MAX_CONNECTIONS		512
#define DEFAULT_PORT				5555
#define CONFIG_STRING_LEN			128

char pidFileName[] = "./server.pid";
char logFileName[] = "./server.log";
CBoxServer* server = NULL;


// Read config file
void read_config(box_server_params& params)
{
	char *variable = NULL, *value = NULL;

	FILE *cfgFile = fopen("./config", "r");
	if (cfgFile != NULL)
	{
		printf("Reading config file...");

		char buf[CONFIG_STRING_LEN];
		while(fgets(buf, CONFIG_STRING_LEN, cfgFile) != NULL)
		{
			if (buf[strlen(buf) - 1] == '\n')
				buf[strlen(buf) - 1] = '\0';

			if (buf[0] == '#')
				continue;

			if ((strlen(buf) > 2) && (buf[strlen(buf) - 1] != '='))
			{
				if (strchr(buf, '=') != NULL)
				{
					variable = strtok(buf, "=");
					value = strtok(NULL, "=");

					if (!strncmp("data_port", variable, 9))
						params.data_port = atoi(value);
					else if (!strncmp("control_port", variable, 12))
						params.control_port = atoi(value);
					else if (!strncmp("max_connections", variable, 15))
						params.max_connections = atoi(value);
					else if (!strncmp("use_syslog", variable, 10))
						params.use_syslog = atoi(value);
					else if (!strncmp("use_thread_pool", variable, 15))
						params.use_thread_pool = atoi(value);
					else if (!strncmp("auth", variable, 4))
						params.auth = atoi(value);
				}
			}
		}
		fclose(cfgFile);
	}
	else
		printf("Warning: Unable to open config file, will be used default settings\n");
}

void on_exit(int param)
{
	// Stop server
	if (server != NULL)
		server->Stop();
	delete server;

	unlink(pidFileName);
	exit(EXIT_SUCCESS);
}


int main(int argc, char* argv[])
{
	pid_t pid = 0;

	FILE *pidFile = NULL;
	box_server_params params;

	// Set handler for signals
	signal(SIGINT, &on_exit);
	signal(SIGTERM, &on_exit);

	// Check count of params
	if (argc < 2 ||
		(!strncmp("start", argv[1], 5) && !strncmp("stop", argv[1], 4) && !strncmp("quit", argv[1], 4)))
	{
		fprintf(stdout, "usage: ./box_server {start|quit|stop}\n");
		exit(EXIT_FAILURE);
	}

	// Check stop
	if (!strncmp("stop", argv[1], 4) || !strncmp("quit", argv[1], 4))
	{
		pidFile = fopen(pidFileName, "r");
		if (pidFile == NULL)
		{
			printf("Server not running\n");
			exit(EXIT_FAILURE);
		}

		printf("Server attempt to stop");
		fscanf(pidFile, "%d", &pid);
		fclose(pidFile);
		unlink(pidFileName);
		printf(",pid = %d\n", pid);
		kill(pid, SIGTERM);
		exit(EXIT_SUCCESS);
	}

	// Check already runned server
	if ((pidFile = fopen(pidFileName,"r")) != NULL)
	{
		fscanf(pidFile, "%d", &pid);
		printf("Box server already running on pid %d\n", pid);
		fclose(pidFile);
		exit(EXIT_SUCCESS);
	}

	// Read config file
	read_config(params);

	// Create child process
	pid = fork();
	if (pid < 0)
	{
		printf("Unable to create child process, %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (pid > 0)	// parent process
	{
		printf("Demon is started, pid = %d\n", pid);

		// Write pid
		pidFile = fopen(pidFileName, "w");
		if (pidFile != NULL)
		{
			fprintf(pidFile, "%d", pid);
			fclose(pidFile);
		}	
		exit(EXIT_SUCCESS);
	}

	// TODO: change working directory
	//char dir[] = ".";
	//if ((chdir(dir)) < 0)
	//{
	//	perror("box_server: Change working directory");
	//	exit(EXIT_FAILURE);
	//}

	// close standard streams
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

	try
	{
		server = new CBoxServer();

		// Init server
		server->Init(params);

		// Start server
		server->Start();

		while(1)
			sleep(1);
	}
	catch(std::exception& ex)
	{

	}
	catch (...)
	{
		printf("Exception by starting server\n");
	}
	
	exit(EXIT_SUCCESS);
}

